<template>
  <div ref="chat-room" class="chat-room">
    <van-nav-bar
      title="websocket聊天室"
      left-text="退出"
      left-arrow
      @click-left="$router.back()"
    />
    <div class="message-list-wrap">
      <div class="message-list">
        <van-cell
          v-for="(message, index) in messageList"
          :key="index"
          :border="false"
          class="message-item"
          :class="{ me: message.name === myName }"
        >
          <div class="speak-name">
            {{ message.name }}
          </div>
          <div class="message-con">
            {{ message.value }}
          </div>
        </van-cell>
      </div>
    </div>
    <div class="chat-input-wrap">
      <textarea
        v-show="false"
        v-model="inputMessage"
        class="chat-input"
        cols="30"
        rows="8"
      ></textarea>
      <van-field
        v-model.trim="inputMessage"
        type="textarea"
        rows="6"
        maxlength="200"
        placeholder="请输入要说的话按 shift+entry 发送"
        @keyup.shift.enter="sendMessage"
      />
      <van-button
        block
        class="send-btn"
        color="linear-gradient(to right, #7647e7, #623f90)"
        @click="sendMessage"
      >
        Send
      </van-button>
    </div>
    <van-popup v-model="nameInputShow" :close-on-click-overlay="false">
      <div class="popup-con">
        <van-field
          v-model.trim="myName"
          maxlength="3"
          placeholder="请输入昵称"
        />
        <van-button
          block
          round
          color="linear-gradient(to right, #7647e7, #623f90)"
          @click="submitName"
        >
          确定
        </van-button>
      </div>
    </van-popup>
  </div>
</template>

<script>
// 使用vant 组件
import {
  List,
  NoticeBar,
  Cell,
  CellGroup,
  Button,
  Field,
  Popup,
  NavBar,
  Toast
} from 'vant'
import Vue from 'vue'
Vue.use(Toast)

import BScroll from 'better-scroll'
export default {
  name: 'Chat',
  components: {
    [List.name]: List,
    [CellGroup.name]: CellGroup,
    [Cell.name]: Cell,
    [NoticeBar.name]: NoticeBar,
    [Field.name]: Field,
    [Popup.name]: Popup,
    [NavBar.name]: NavBar,
    [Button.name]: Button
  },
  data() {
    return {
      retryTime: 0,
      ws: null,
      websock: null,
      scroll: null,
      messageList: [],
      inputMessage: '',
      nameInputShow: false,
      myName: ''
    }
  },
  watch: {
    messageList() {
      this.$nextTick(() => {
        this.scroll.refresh()
        this.scroll.scrollTo(0, this.scroll.maxScrollY)
      })
    }
  },
  created() {
    if (window.localStorage.getItem('messageList')) {
      this.messageList = JSON.parse(window.localStorage.getItem('messageList'))
    }
    if (window.localStorage.getItem('myName')) {
      this.myName = window.localStorage.getItem('myName')
      this.nameInputShow = false
      this.initWebSocket()
    } else {
      this.nameInputShow = true
    }
  },
  mounted() {
    // eslint-disable-next-line no-unused-vars
    this.scroll = new BScroll('.message-list-wrap', {
      scrollY: true,
      click: true,
      mouseWheel: true
    })

  },
  methods: {
    receiveMsg(msgData) {
      const msg = msgData
      if (msg.type === 'login') {
        this.$toast(`${msg.data}进入了聊天室`)
      } else {
        this.messageList.push(msg)
        if (this.messageList.length > 100) {
          this.messageList = this.messageList.slice(
            this.messageList.length - 100
          )
        }
        window.localStorage.setItem(
          'messageList',
          JSON.stringify(this.messageList.slice(this.messageList.length - 10))
        )
      }
    },
    sendMessage() {
      if (this.inputMessage) {
        // this.messageList.push({ name: this.myName, value: this.inputMessage })
        // this.inputMessage = ''
        // if (this.messageList.length > 100) {
        //   this.messageList = this.messageList.slice(
        //     this.messageList.length - 100
        //   )
        // }
        // window.localStorage.setItem(
        //   'messageList',
        //   JSON.stringify(this.messageList.slice(this.messageList.length - 10))
        // )
        let sendData = { name: this.myName, value: this.inputMessage }
        if (this.inputMessage.indexOf('@') != -1) {
          sendData.to = this.getAtName(this.inputMessage)
        }
        // this.ws.send(JSON.stringify(sendData))
        this.websocketsend(JSON.stringify(sendData))
        this.inputMessage = ''
      } else {
        this.$toast('不能发送空白消息')
      }
    },
    submitName() {
      if (this.myName) {
        window.localStorage.setItem('myName', this.myName)
        this.nameInputShow = false
        this.ws.send(
          JSON.stringify({
            id: this.myName,
            login: true
          })
        )
      } else {
        this.$toast('请输入昵称')
      }
    },
    getAtName(str) {
      // eslint-disable-next-line no-useless-escape
      const index = str.lastIndexOf('\@')
      str = str.substring(index + 1, index + 4)
      return str
    },

    initWebSocket() {
      // 初始化weosocket
      const wsUrl = 'ws://localhost:4001'
      this.websock = new WebSocket(wsUrl)
      this.websock.onmessage = this.websocketonmessage
      this.websock.onopen = this.websocketonopen
      this.websock.onerror = this.websocketonerror
      this.websock.onclose = this.websocketclose
    },
    websocketonopen() {
      this.retryTime = 0
      // 连接建立之后执行send方法发送数据
      if (this.myName) {
        let actions = {
          id: this.myName,
          login: true
        }
        this.websocketsend(JSON.stringify(actions))
      }
    },
    websocketonerror() {
      // 连接建立失败重连
      this.retryTime++
      if(this.retryTime<=3) {
        this.initWebSocket()
      }

    },
    websocketonmessage(e) {
      // 数据接收
      const resData = JSON.parse(e.data)
      this.receiveMsg(resData)
    },
    websocketsend(Data) {
      // 数据发送
      this.websock.send(Data)
    },
    websocketclose(e) {
      // 关闭
      console.log('断开连接', e)
      this.$toast('断开连接', e)
    }
  }
}
</script>

<style scoped lang="less">
.chat-room {
  min-height: 100vh;
  background-color: #f1f3f5;
  .message-list-wrap {
    box-sizing: border-box;
    height: calc(100vh - 256px);
    padding: 10px 0;
    overflow: hidden;
  }
  .speak-name {
    position: absolute;
    top: 0;
    left: 0;
    box-sizing: border-box;
    display: block;
    width: 40px;
    height: 40px;
    overflow: hidden;
    font-size: 12px;
    font-weight: bold;
    line-height: 40px;
    color: #333333;
    text-align: center;
    background-color: #cccccc;
    border-radius: 50%;
  }
  .message-con {
    position: relative;
    display: inline-block;
    min-height: 24px;
    padding: 10px;
    word-break: break-all;
    word-wrap: break-word;
    background-color: #ffffff;
    border-radius: 6px;
    &::before {
      position: absolute;
      top: 10px;
      left: -7px;
      display: block;
      width: 0;
      height: 0;
      content: '';
      border-top: 6px solid transparent;
      border-right: 8px solid white;
      border-bottom: 6px solid transparent;
    }
    &::after {
      display: none;
    }
  }
  /deep/ .message-item {
    position: relative;
    padding: 2.667vw 2.267vw;
    margin-bottom: 10px;
    background-color: transparent;
    &:last-child {
      margin-bottom: 0;
    }
    .van-cell__value {
      padding: 0 50px;
    }

    &.me {
      .speak-name {
        position: absolute;
        top: 0;
        right: 0;
        left: auto;
      }
      .message-con {
        float: right;
        background-color: #9eea6a;
        &::before {
          display: none;
        }
        &::after {
          position: absolute;
          top: 10px;
          right: -7px;
          display: block;
          width: 0;
          height: 0;
          content: '';
          border-top: 6px solid transparent;
          border-bottom: 6px solid transparent;
          border-left: 8px solid #9eea6a;
        }
      }
    }
  }
  .chat-input-wrap {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    border-top: 1px solid #cac9c9;
  }
  .chat-input {
    box-sizing: border-box;
    display: block;
    width: 100%;
    padding: 10px;
    background-color: #e5e4e3;
    border: none;
  }
  .popup-con {
    padding: 10px 20px;
  }
}
</style>
